package com.xul.crowd.controller;

import com.xul.crowd.api.MysqlRemoteService;
import com.xul.crowd.config.OSSProperties;
import com.xul.crowd.constant.CrowdConstant;
import com.xul.crowd.util.CrowdUtil;
import com.xul.crowd.util.ResultEntity;
import com.xul.entity.vo.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpSession;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

/**
 * @author xul
 * @create 2021-07-30 16:35
 */
@Controller
public class ProjectConsumerController {

    @Autowired
    private OSSProperties ossProperties;

    @Autowired
    private MysqlRemoteService mysqlRemoteService;

    /**
     * oos上传头图和详情图 并把表单的数据存入到session中 session存入redis中
     *
     * @param projectVO
     * @param headerPicture
     * @param detailPictureList
     * @param session
     * @param modelMap
     * @return
     * @throws IOException
     */
    @RequestMapping("create/project/information.html")
    public String saveProjectBasicInfo(
            // 接受除了上传图片之外的其他普通数据
            ProjectVO projectVO,
            // 接受上传的头图
            MultipartFile headerPicture,
            // 接受上传的详情图片
            List<MultipartFile> detailPictureList,
            // 用来收集了一部分的数据的ProjectVO对象存入到Session域
            HttpSession session,
            // 用来在当前的操作失败返回上一个表单页面时携带的提示消息
            ModelMap modelMap
    ) throws IOException {
        // 完成头图上传
        // 1.获取当前 headerPicture 对象是否为空
        boolean headerPictureEmpty = headerPicture.isEmpty();
        if (headerPictureEmpty) {
            // 如果没有上传头图返回表单页面并提示消息
            modelMap.addAttribute(CrowdConstant.ATTR_NAME_MESSAGE, CrowdConstant.MESSAGE_HEADER_PIC_EMPTY);
            return "project-launch";
        }
        // 2.如果用户确实上传了有内容的文件,则执行上传
        ResultEntity<String> uploadHeaderPicResultEntity = CrowdUtil.uploadFileToOss(
                ossProperties.getEndPoint(),
                ossProperties.getAccessKeyId(),
                ossProperties.getAccessKeySecret(),
                headerPicture.getInputStream(),
                ossProperties.getBucketName(),
                ossProperties.getBucketDomain(),
                headerPicture.getOriginalFilename()
        );
        String result = uploadHeaderPicResultEntity.getResult();
        // 3.判断头图是否上传成功
        if (ResultEntity.SUCCESS.equals(result)) {
            // 4.从返回数据中获取图片的访问路径
            String picResultEntityData = uploadHeaderPicResultEntity.getData();
            // 5.存入ProjectVO对象中
            projectVO.setHeaderPicturePath(picResultEntityData);
        } else {
            // 6如果上传失败则返回到表单页面显示错误消息
            modelMap.addAttribute(CrowdConstant.ATTR_NAME_MESSAGE, CrowdConstant.MESSAGE_HEADER_PIC_UPLOAD_FAILED);
            return "project-launch";
        }

        // 上传详情图片
        // 创建一个用来存放详情图片的集合
        List<String> detailPicturePathList = new ArrayList<String>();
        // 2.检查 detailPictureList 是否有效
        if (detailPictureList == null || detailPictureList.size() == 0) {
            modelMap.addAttribute(CrowdConstant.ATTR_NAME_MESSAGE, CrowdConstant.MESSAGE_DETAIL_PIC_EMPTY);
            return "project-launch";
        }

        // 遍历detailPictureList集合
        for (MultipartFile detailPicture : detailPictureList) {
            // 4.当前 detailPicture 是否为空
            if (detailPicture.isEmpty()) {
                // 5.检测到详情图片中单个文件为空也是回去显示错误消息
                modelMap.addAttribute(CrowdConstant.ATTR_NAME_MESSAGE, CrowdConstant.MESSAGE_DETAIL_PIC_EMPTY);
                return "project-launch";
            }
            // 执行上传
            ResultEntity<String> detailUploadHeaderPicResultEntity = CrowdUtil.uploadFileToOss(
                    ossProperties.getEndPoint(),
                    ossProperties.getAccessKeyId(),
                    ossProperties.getAccessKeySecret(),
                    detailPicture.getInputStream(),
                    ossProperties.getBucketName(),
                    ossProperties.getBucketDomain(),
                    detailPicture.getOriginalFilename()
            );
            // 检查上传结果
            String detailUploadResult = detailUploadHeaderPicResultEntity.getResult();
            if (ResultEntity.SUCCESS.equals(detailUploadResult)) {
                String detailPicturePath = detailUploadHeaderPicResultEntity.getData();
                // 收集刚刚上传的图片的访问路径
                detailPicturePathList.add(detailPicturePath);
            } else {
                // 9.如果上传失败则返回到表单页面并显示错误消息
                modelMap.addAttribute(CrowdConstant.ATTR_NAME_MESSAGE, CrowdConstant.MESSAGE_DETAIL_PIC_UPLOAD_FAILED);
                return "project-launch";
            }
        }

        // 将存放了详情图片访问路径的集合存入ProjectVO中
        projectVO.setDetailPicturePathList(detailPicturePathList);
        // 将ProjectVO对象存入到Session中
        //存入session
        session.setAttribute(CrowdConstant.ATTR_NAME_TEMPLE_PROJECT, projectVO);
        // 以完整的访问路径前往下一个收集信息的页面
        return "redirect:http://localhost:/project/return/info/page.html";

    }

    /**
     * 回报设置里面的添加图片
     *
     * @param returnPicture
     * @return
     * @throws IOException
     */
    @ResponseBody
    @RequestMapping("create/upload/return/picture.json")
    public ResultEntity<String> uploadReturnPicture(MultipartFile returnPicture) throws IOException {
        // 执行文件上传
        ResultEntity<String> uploadReturnPicResultEntity = CrowdUtil.uploadFileToOss(
                ossProperties.getEndPoint(),
                ossProperties.getAccessKeyId(),
                ossProperties.getAccessKeySecret(),
                returnPicture.getInputStream(),
                ossProperties.getBucketName(),
                ossProperties.getBucketDomain(),
                returnPicture.getOriginalFilename()
        );
        // 返回上传结果
        return uploadReturnPicResultEntity;
    }

    /**
     * 回报设置里面的添加回报信息加入到projectVO中 一起存入到session中
     *
     * @param returnVO
     * @param session
     * @return
     */
    @ResponseBody
    @RequestMapping("create/save/return.json")
    public ResultEntity<String> saveReturn(ReturnVO returnVO, HttpSession session) {
        try {
            // 1.从之前的session域中读取之前缓存的ProjectVO对象
            ProjectVO projectVO = (ProjectVO) session.getAttribute(CrowdConstant.ATTR_NAME_TEMPLE_PROJECT);
            // 2.判断projectVO是否为为null
            if (projectVO == null) {
                return ResultEntity.failed(CrowdConstant.MESSAGE_TEMPLE_PROJECT_MISSING);
            }
            // 3.从projectVO对象中获取存储回报信息得集合
            List<ReturnVO> returnVOList = projectVO.getReturnVOList();
            // 4.判断returnVOList集合是否有效
            if (returnVOList == null || returnVOList.size() == 0) {
                // 5.创建集合对象对returnVOList经行初始化
                returnVOList = new ArrayList<>();
                // 6.为了以后能够正常使用这个集合,设置到ProjectVO对象中
                projectVO.setReturnVOList(returnVOList);
            }
            // 7.将收集的表单数据的returnVO对象存入到集合
            returnVOList.add(returnVO);
            // 8.把数据有变化的ProjectVO对象重新存入Session域,以确保数据最终能够存入到Redis中
            session.setAttribute(CrowdConstant.ATTR_NAME_TEMPLE_PROJECT, projectVO);
            // 9.所有操作成功
            return ResultEntity.successWithData();
        } catch (Exception e) {
            e.printStackTrace();
            return ResultEntity.failed(e.getMessage());
        }
    }

    /**
     * 所有信息都加入到projectVO中 一起存入到session中 然后调用远程方法保存到数据库的各个表中
     *
     * @param modelMap
     * @param session
     * @param memberConfirmInfoVO
     * @return
     */
    @RequestMapping("create/confirm.html")
    public String saveConfirm(ModelMap modelMap, HttpSession session, MemberConfirmInfoVO memberConfirmInfoVO) {
        // 1.从Session域读取之前临时存储的ProjectVO对象
        ProjectVO projectVO = (ProjectVO) session.getAttribute(CrowdConstant.ATTR_NAME_TEMPLE_PROJECT);
        // 2.如果ProjectVO为null
        if (projectVO == null) {
            throw new RuntimeException(CrowdConstant.MESSAGE_TEMPLE_PROJECT_MISSING);
        }
        // 3.将确认信息数据设置到projectVO对象中
        projectVO.setMemberConfirmInfoVO(memberConfirmInfoVO);
        // 4.从session域读取当前用户登录
        MemberLoginVo memberLoginVo = (MemberLoginVo) session.getAttribute(CrowdConstant.ATTR_NAME_LOGIN_MEMBER);
        Integer memberId = memberLoginVo.getId();
        // 5.调用远程方法保存projectVO对象
        ResultEntity<String> saveResultEntity = mysqlRemoteService.saveProjectVORemote(projectVO, memberId);
        // 6.判断远程的保存操作是否成功
        String result = saveResultEntity.getResult();
        if (ResultEntity.FAILED.equals(result)) {
            modelMap.addAttribute(CrowdConstant.ATTR_NAME_MESSAGE, saveResultEntity.getMessage());
            return "project-confirm";
        }
        // 7.将临时的ProjectVO对象从Session域中删除
        session.removeAttribute(CrowdConstant.ATTR_NAME_TEMPLE_PROJECT);
        // 8.如果远程保存成功则跳转最终完成页面
        return "redirect:http://localhost:/project/create/success.html";
    }


    /**
     * 根据projectId查询出详情信息 包括回报数据 头图数据 三表关联
     *
     * @param projectId
     * @param model
     * @return
     */
    @RequestMapping("get/project/detail/{projectId}")
    public String getProjectDetail(@PathVariable("projectId") Integer projectId, Model model) {
        ResultEntity<DetailProjectVO> detailProjectVOResult = mysqlRemoteService.getDetailProjectVORemote(projectId);
        if (ResultEntity.SUCCESS.equals(detailProjectVOResult.getResult())) {
            DetailProjectVO detailProjectVO = detailProjectVOResult.getData();
            model.addAttribute("detailProjectVO", detailProjectVO);
        }
        return "project-show-detail";
    }


}
